﻿//-----------------------------------------------------------------------------------------------------------
// WBFSSync Project by Omega Frost 
// http://wbfssync.codeplex.com/
//
// WBFSSync is Licensed under the terms of the 
// Microsoft Reciprocal License (Ms-RL)
//-----------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using WBFSe3;

namespace WbfsSync.Core.Operations
{
    //-------------------------------------------------------------------------------------------------------
    //
    //-------------------------------------------------------------------------------------------------------
    public delegate void OperationDelegate(Operation sender, WbfsError error, int element);


    //-------------------------------------------------------------------------------------------------------
    //
    //-------------------------------------------------------------------------------------------------------
    public enum OperationType
    {
        Copy,
        Move,
        Load,
        Cover,
        Update,
        Delete,
    }


    //-------------------------------------------------------------------------------------------------------
    //
    //-------------------------------------------------------------------------------------------------------
    public abstract class Operation
    {
        //---------------------------------------------------------------------------------------------------
        //
        //---------------------------------------------------------------------------------------------------
        public String Name;
        public Thread Thread;
        public OperationType Type;

        public long Current;
        public long CurrentCount;

        public long CurrentNotifyStep;
        protected long CurrentLastUpdate;

        public long Total;
        public long TotalCount;
        
        public Boolean IsCanceled;
        public Boolean IsPaused;


        //---------------------------------------------------------------------------------------------------
        //
        //---------------------------------------------------------------------------------------------------
        public event OperationDelegate StepUpdated;
        public event OperationDelegate StepCompleted;
        public event OperationDelegate Completed;


        //---------------------------------------------------------------------------------------------------
        //
        //---------------------------------------------------------------------------------------------------
        public Operation(String name, OperationType type)
        {
            this.Name = name;
            this.Type = type;

            this.Current = 0;
            this.CurrentCount = 0;

            this.CurrentNotifyStep = 0;
            this.CurrentLastUpdate = 0;

            this.Total = 0;
            this.TotalCount = 0;
        }


        //---------------------------------------------------------------------------------------------------
        //
        //---------------------------------------------------------------------------------------------------
        public void Pause()
        {
            this.IsPaused = true;
        }


        //---------------------------------------------------------------------------------------------------
        //
        //---------------------------------------------------------------------------------------------------
        public void Resume()
        {
            this.IsPaused = false;
        }


        //---------------------------------------------------------------------------------------------------
        //
        //---------------------------------------------------------------------------------------------------
        public void Cancel()
        {
            this.IsCanceled = true;

            if (this.Completed != null)
                this.Completed(this, WbfsError.Cancel, -1);
        }


        //---------------------------------------------------------------------------------------------------
        //
        //---------------------------------------------------------------------------------------------------
        public void Step(long step, WbfsError error)
        {
            if (step >= 0) this.Current += step;
            else this.Current = this.CurrentCount;

            if (this.Current >= this.CurrentCount)
            {
                this.CurrentNotifyStep = this.Current;
                if (this.StepUpdated != null)
                {
                    this.StepUpdated(this, error,
                        (int)this.Total);
                }

                if (this.StepCompleted != null)
                    this.StepCompleted(this, error,
                        (int)this.Total);

                this.Current = 0;
                this.CurrentLastUpdate = 0;

                this.Total++;

                if (this.Total == this.TotalCount)
                {
                    if (this.Completed != null)
                        this.Completed(this, error, -1);
                }
            }
            else
            {
                long delta = this.Current - this.CurrentLastUpdate;
                if (delta >= this.CurrentNotifyStep)
                {
                    this.CurrentNotifyStep = this.Current;
                    if (this.StepUpdated != null)
                    {
                        this.StepUpdated(this, error,
                            (int)this.Total);
                    }
                }
            }
        }
    }
}
